<?php

namespace lc\wechat;

use lc\Http;
use lc\memcache\MemCacheToken;

/**
 * 管理临时素材
 * 官方文档：
 * http://mp.weixin.qq.com/wiki/5/963fc70b80dc75483a271298a76a8d59.html
 * http://mp.weixin.qq.com/wiki/11/07b6b76a6b6e8848e855a435d5e34a5f.html
 */
class Temporary
{
    /**
     * 可用的类型，类型支持的格式参照官方文档.
     *
     * @var array
     */
    protected $allowTypes = array('image', 'voice', 'video', 'thumb');

    const API_GET = 'https://api.weixin.qq.com/cgi-bin/media/get';

    const API_UPLOAD = 'https://api.weixin.qq.com/cgi-bin/media/upload';

    private $mem;
    private $ptAppid;  //平台appid
    private $appid;  //平台appid


    public function __construct($ptAppid, $appid)
    {
        $this->mem = new MemCacheToken();
        $this->ptAppid = $ptAppid;
        $this->appid = $appid;
    }

    /**
     * 下载资源并保存到指定文件夹
     *
     * @param string $mediaId		
     * @param string $directory		文件夹路径
     * @param string $filename		文件名，不要带扩展名，会自动加上,默认mediaId
     *
     * @return string	成功返回文件名.扩展名，失败返回官方错误码
     *
     * @throws 
     */
    public function download($mediaId, $directory, $filename = '', $type = 'sound')
    {
        if (!is_dir($directory) || !is_writable($directory)) {
            //throw new InvalidArgumentException("Directory does not exist or is not writable: '$directory'.");
        }

        $filename = $filename ?: $mediaId;
        $stream = $this->getStream($mediaId);
        if ($type == 'sound') {
            file_put_contents($directory . '/' . $filename, $stream);
            return $filename;
        }
        $ext = pathinfo($stream, PATHINFO_EXTENSION);
        if ($ext == '') {
            file_put_contents($directory . '/' . $filename, $stream);
            return $filename;
        }
        file_put_contents($directory . '/' . $filename . $ext, $stream);
        return $filename . $ext;
    }

    /**
     * 获取素材.
     *
     * @param string $mediaId
     *
     * @return mixed
     *
     * @throws 
     */
    private function getStream($mediaId)
    {
        $response = $this->post(self::API_GET, ['media_id' => $mediaId]);

        return $response;
    }

    /**
     * 上传临时素材.
     *
     * @param string $type	媒体文件类型，分别有图片（image）、语音（voice）、视频（video）和缩略图（thumb）
     * @param string $path
     *
     * @return string
     *
     */
    public function uploadM($type, $path)
    {
        if (!file_exists($path) || !is_readable($path)) {
            //throw new InvalidArgumentException("File does not exist, or the file is unreadable: '$path'");
        }

        if (!in_array($type, $this->allowTypes, true)) {
            //throw new InvalidArgumentException("Unsupported media type: '{$type}'");
        }
        return $this->upload($type, self::API_UPLOAD, $path);
    }

    /**
     * 上传图片.
     *
     * @param $path
     *
     * @return string
     *
     * @throws 
     */
    public function uploadImage($path)
    {
        return $this->upload('image', $path);
    }

    /**
     * 上传视频.
     *
     * @param $path
     *
     * @return string
     *
     * @throws 
     */
    public function uploadVideo($path)
    {
        return $this->upload('video', $path);
    }

    /**
     * 上传声音.
     *
     * @param $path
     *
     * @return string
     *
     * 
     */
    public function uploadVoice($path)
    {
        return $this->upload('voice', $path);
    }

    /**
     * 上传封面.
     *
     * @param $path
     *
     * @return string     
     * 
     */
    public function uploadThumb($path)
    {
        return $this->upload('thumb', $path);
    }

    /**
     * 上传文件
     * @param string $type      媒体文件类型，分别有图片（image）、语音（voice）、视频（video）和缩略图（thumb）
     * @param string $url       请求URL
     * @param string $file      全路径+文件名
     */
    private function upload($type, $url, $file, array $form = [])
    {
        foreach ($form as $name => $contents) {
            $data[$name] = $contents;
        }
        $data['media'] =  new \CURLFile($file);
        //print_r($data);
        $token = $this->mem->getTokenByPt($this->ptAppid, $this->appid);

        $url = $url . "?access_token=" . $token->token . "&type=" . $type;

        return Http::send($url, $data);
    }

    private function post($url, $data = NULL)
    {
        $token = $this->mem->getTokenByPt($this->ptAppid, $this->appid);
        $url .= "?access_token=" . $token->token;
        return $this->httpsRequest($url, $data);
    }
    public  function httpsRequest($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
}
